package website.haicheng.server.handlers;

import cn.hutool.core.exceptions.ExceptionUtil;
import website.haicheng.server.common.constant.AttrConstant;
import website.haicheng.server.common.enums.MessageEnum;
import website.haicheng.server.model.Message;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: 582895699@qq.com
 * @Desctription: 上线、下线、数据读取和移除处理逻辑
 * @Date: Created in 2021/12/1 15:51
 */
@Slf4j
@ChannelHandler.Sharable
public class ServerHandler extends SimpleChannelInboundHandler<Message> {

    private MessageHandler messageHandler;

    public ServerHandler(MessageHandler handler) {
        this.messageHandler = handler;
    }

    /**
     * 上线
     *
     * @param ctx ChannelHandlerContext
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channel.attr(AttrConstant.ATTRIBUTE_KEY_CHANNEL_ID).set(channel.id().asLongText());
        log.info("客户端上线;channel:{}", channel.id());
    }

    /**
     * 离线
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        Message message = new Message();
        message.setType(MessageEnum.CLOSE_CHANNEL.name());
        messageHandler.process(channel, message);
        log.info("客户端离线;channel:{}", channel.id());
    }

    /**
     * 异常处理
     *
     * @param ctx   ChannelHandlerContext
     * @param cause Throwable
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("异常处理；cause：{}", ExceptionUtil.stacktraceToString(cause));
        ctx.channel().close();
    }

    /**
     * 数据读取
     *
     * @param channelHandlerContext ChannelHandlerContext
     * @param message               Message
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Message message) throws Exception {
        messageHandler.process(channelHandlerContext.channel(), message);
    }
}
